package com.qf.shiro;

import com.alibaba.druid.util.StringUtils;
import com.qf.pojo.DtsAdmin;
import com.qf.service.AdminService;
import com.qf.service.PermissionService;
import com.qf.service.RoleService;
import com.qf.util.bcrypt.BCryptPasswordEncoder;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.sound.sampled.AudioFileFormat;
import java.util.List;
import java.util.Set;

/**
 * projectName: wokepase1
 *
 * @author: 强力
 * time: 2021/9/10 20:33
 * description:
 */
public class AdminAuthorizingRealm extends AuthorizingRealm {

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;
    public static  final Logger logger= LoggerFactory.getLogger(AdminAuthorizingRealm.class);

    /**
     * 用户登录成功后对用户进行授权,授予用户对应的角色和权限
     * @param ppc
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection ppc) {
        //1.获取认证的用户对象
        DtsAdmin admin= (DtsAdmin) getAvailablePrincipal(ppc);
        //2.从用户对象中获取用户拥有的角色数组
        Integer[] roleIds = admin.getRoleIds();
        //3.根据角色数组库中查询
        //查询对应用户角色名称集合
        Set<String> roles = roleService.queryRoles(roleIds);
        //查询对应用户权限集合
        Set<String> perm = permissionService.findPermByroleId(roleIds);
        //4.创建Shiro对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //5.将获取角色存入shiro框架中
        info.setRoles(roles);
        //6.将获取权限字符串存入shiro框架中
        info.setStringPermissions(perm);
        //7.返回shiro需要的权限对象
        return info;
    }

    /**
     * 登录用户名密码校验
     * @param
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {


      //1.获取用户页面输入的用户名密码
            UsernamePasswordToken utoken= (UsernamePasswordToken) token;
        String username = utoken.getUsername();
        String password =new String(utoken.getPassword());

        //2.判断用户名密码是否为空
        if (StringUtils.isEmpty(username)) {
            throw new AccountException("用户名不能为空");
         }
        if (StringUtils.isEmpty(password)) {
            throw new AccountException("密码不能为空");
        }
        //3.根据用户名查询数据库用户名对象对比并判断
        List<DtsAdmin> admin = adminService.findAdmin(username);

        if (admin == null||admin.size()==0) {
            logger.error("无此用户,username="+username);
            throw new UnknownAccountException("找不到指定用户");

        }
        if (admin.size()>1){
            logger.error("存在相同用户名,username="+username);
            throw new UnknownAccountException("用户名重复");
        }

        //4.验证输入的用户密码与数据库中用户对象密码是否一致
        DtsAdmin dtsAdmin = admin.get(0);
        BCryptPasswordEncoder encoder=new BCryptPasswordEncoder();
        //校验密码 第一参数明文密码 第二参数是加密后的密文密码
        boolean flag = encoder.matches(password, dtsAdmin.getPassword());


if (!flag){
    logger.error("用户名密码不正确");
    throw new UnknownAccountException("密码错误");
}
        //5.封装shiro框架需要的用户对象交给shiro管理
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, dtsAdmin.getUsername());

        return info;
    }
}
